﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Com = System.Runtime.InteropServices.ComTypes;

namespace MSIXML
{
    public class API
    {
        public const int ERROR_NO_DATA = 232;
        public const int ERROR_NO_MORE_ITEMS = 259;

        public static long MAKELONGLONG(int a, int b)
        {
            return (long)((long)(a & 0xffffffff) | ((long)(b & 0xffffffff) << 32));
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MSIFILEHASHINFO
        {
            public int dwFileHashInfoSize;
            public int dwHash1;
            public int dwHash2;
            public int dwHash3;
            public int dwHash4;
        }

        #region MSI
        [DllImport("msi")]
        public static extern IntPtr MsiGetActiveDatabase(
            IntPtr prod
            );
        public delegate int InstallUIHandler(IntPtr context, int messageType, string message);
        [DllImport("msi")]
        public static extern InstallUIHandler MsiSetExternalUI(
            InstallUIHandler proc,
            int messages,
            IntPtr context
            );
        [DllImport("msi")]
        public static extern int MsiProcessMessage(
            IntPtr hInstall,
            int eMessageType,
            IntPtr hRecord
            );
        [DllImport("msi")]
        public static extern int MsiSequence(
            IntPtr product,
            string table,
            int reserved
            );
        [DllImport("msi")]
        public static extern int MsiGetFileSignatureInformation(
            string szSignedObjectPath,
            int dwFlags,
            ref IntPtr ppcCertContext,
            IntPtr pbHashData,
            ref int pcbHashData
            );
        [DllImport("msi")]
        public static extern int MsiCreateTransformSummaryInfo(
            IntPtr database,
            IntPtr databaseRef,
            string xfrmfile,
            int errcond,
            int validation
            );
        [DllImport("msi")]
        public static extern int MsiDeterminePatchSequence(string productCode, string userSid, int context, int cPatchInfo, ref MSIPATCHSEQUENCE[] patches);
        [DllImport("msi")]
        public static extern int MsiApplyMultiplePatches(string patchPackages, string prodCode, string propertyList);
        [DllImport("msi")]
        public static extern int MsiEnumPatchesEx(string prodCode, string userSid, int context, int filter, int index,
            ref string patchCode, ref string targetProdCode, ref int targetContext, ref string targetUserSid, ref int pcchTargetUserSid);
        [DllImport("msi")]
        public static extern int MsiGetPatchInfoEx(string patchCode, string productCode, string userId, int context, string property, ref string val, ref int cchVal);
        [DllImport("msi")]
        public static extern int MsiEnumProductsEx(string productCode, string userSid, int context, int index, ref string installedProdCode, ref int installContext, ref string sid, ref int cchSid);
        [DllImport("msi")]
        public static extern int MsiGetProductInfoEx(string productCode, string userSid, int context, string property, ref string value, ref int cchValue);
        [DllImport("msi")]
        public static extern int MsiQueryFeatureStateEx(string productCode, string userSid, int context, string feature, ref int installState);
        [DllImport("msi")]
        public static extern int MsiQueryComponentState(string productCode, string userSid, int context, string component, ref int dwState);
        [DllImport("msi")]
        public static extern int MsiExtractPatchXMLData(string patchPath, int reserved, ref string xmlData, ref int cchXMLdata);
        [DllImport("msi")]
        public static extern int MsiDetermineApplicablePatches(string prodPackagePath, int cPatchInfo, ref MSIPATCHSEQUENCE[] patchInfo);
        [DllImport("msi")]
        public static extern int MsiSourceListEnumSources(string prodOrPatchCode, string userSid, int context, int options, int index, ref string source, ref int cchSource);
        [DllImport("msi")]
        public static extern int MsiSourceListAddSourceEx(string prodOrPatchCode, string userSid, int context, int options, string source, int index);
        [DllImport("msi")]
        public static extern int MsiSourceListClearSource(string prodOrPatchCode, string userSid, int context, int options, string source);
        [DllImport("msi")]
        public static extern int MsiSourceListClearAllEx(string prodOrPatchCode, string userSid, int context, int options);
        [DllImport("msi")]
        public static extern int MsiSourceListForceResolutionEx(string prodOrPatchCode, string userSid, int context, int options);
        [DllImport("msi")]
        public static extern int MsiSourceListGetInfo(string prodOrPatchCode, string userSid, int context, int options, string property, ref string val, ref int cchVal);
        [DllImport("msi")]
        public static extern int MsiSourceListSetInfo(string prodOrPatchCode, string userSid, int context, int options, string property, string val);
        [DllImport("msi")]
        public static extern int MsiSourceListEnumMediaDisks(string prodOrPatchCode, string userSid, int context, int options, int index, ref int diskId, ref string volLabel, ref int cchVolLabel, ref string diskPrompt, ref int cchDiskPrompt);
        [DllImport("msi")]
        public static extern int MsiSourceListAddMediaDisk(string prodOrPatchCode, string userSid, int context, int options, int diskId, string volLabel, string diskPrompt);
        [DllImport("msi")]
        public static extern int MsiSourceListClearMediaDisk(string prodOrPatchCode, string userSid, int context, int options, int diskId);
        [DllImport("msi")]
        public static extern int MsiRemovePatches(string patchList, string productCode, int installType, string propertyList);
        [DllImport("msi", CharSet = CharSet.Auto)]               // UI level             // handle of owner window
        public static extern int MsiSetInternalUI(int dwUILevel, ref IntPtr winhandle);
        [DllImport("msi")]
        public static extern int MsiEnableUIPreview(IntPtr msihandle,
            ref IntPtr preview_handle);       // returned handle for UI preview capability
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiPreviewDialog(IntPtr preview_handle,
            string DialogName);      // dialog to display, Dialog table key
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiPreviewBillboard(IntPtr preview_handle,
            string ControlName,      // name of control that accepts billboards
            string Billboard);       // name of billboard to display
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnableLog(
            int LogMode,           // bit flags designating operations to report
            string LogFile,           // log file, or NULL to disable logging
            int LogAttributes);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiFormatRecord(
            IntPtr hInstall,
            IntPtr hRecord,
            string szResultBuf,
            ref int pcchResultBuf
            );
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiOpenPackage(string path, ref IntPtr product);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiOpenPackageEx(string path, int options, ref IntPtr product);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiOpenProduct(string product, ref IntPtr productHandle);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiDoAction(IntPtr hInst, string actioun);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetFileHash(string path, int options, ref MSIFILEHASHINFO info);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiQueryProductState(
            string Product);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetProductInfo(
            string Product,      // product code
            string Attribute,    // attribute name, case-sensitive
            StringBuilder Buffer,     // returned value, NULL if not desired ref?
            ref int length);       // in/out buffer character count
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiInstallProduct(
            string PackagePath,    // location of package to install
            string CommandLine);   // command line <property settings>
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiConfigureProduct(
            string Product,        // product code
            int iInstallLevel,    // how much of the product to install
            int eInstallState);   // local/source/default/absent/lock/uncache
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiReinstallProduct(
            string Product,        // product code
            int ReinstallMode); // one or more REINSTALLMODE modes
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetProductCode(
            string Component,   // component Id registered for this product
            StringBuilder Buffer39);      // returned string GUID, sized for 39 characters
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetUserInfo(
            string Product,        // product code, string GUID
            StringBuilder UserNameBuffer,    // return user name           
            ref int UserNameBufferLength, // in/out buffer character count
            StringBuilder OrgNameBuffer,     // return company name           
            ref int OrgNameBufferLength,  // in/out buffer character count
            StringBuilder SerialBuffer,      // return product serial number
            ref int SerialBufferLength);  // in/out buffer character count
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetSourcePath(
            IntPtr hInstall, string folder, StringBuilder outBuf, ref int outBufLength);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiCollectUserInfo(
            string Product);     // product code, string GUID
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiOpenDatabase(string dbpath,
            int persist,
            ref IntPtr msihandle);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiDatabaseImport(IntPtr msihandle,
            string FolderPath,     // folder containing archive files
            string FileName);      // table archive file to be imported
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiDatabaseExport(IntPtr msihandle,
            string TableName,      // name of table in database <case-sensitive>
            string FolderPath,     // folder containing archive files
            string FileName);      // name of exported table archive file	
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiDatabaseMerge(IntPtr msihandle,
            IntPtr msihandle2,    // database to be merged into hDatabase
            string TableName);      // name of non-persistent table to receive errors
        [DllImport("msi")]
        public static extern int MsiDatabaseCommit(IntPtr msihandle);
        [DllImport("msi")]
        public static extern int MsiDatabaseGenerateTransform(IntPtr database, IntPtr databaseRef, string xfrmfile, int resv1, int resv2);
        [DllImport("msi")]
        public static extern int MsiDatabaseApplyTransform(IntPtr database, string xfrmfile, int conditions);
        [DllImport("msi")]
        public static extern int MsiGetDatabaseState(IntPtr msihandle);
        [DllImport("msi")]
        public static extern int MsiDatabaseOpenView(IntPtr msihandle, string query, ref IntPtr viewhandle);
        [DllImport("msi")]
        public static extern int MsiViewExecute(IntPtr viewhandle, IntPtr recordhandle);
        [DllImport("msi")]
        public static extern int MsiViewFetch(IntPtr viewhandle, ref IntPtr recordhandle);
        [DllImport("msi")]
        public static extern int MsiViewModify(IntPtr viewhandle,
            int eModifyMode,         // modify action to perform
            IntPtr recordhandle);            // record obtained from fetch, or new record
        [DllImport("msi")]
        public static extern int MsiViewGetColumnInfo(IntPtr viewhandle,
            int eColumnInfo,        // retrieve columns names or definitions
            ref IntPtr recordhandle);          // returned data record containing all names or definitions
        [DllImport("msi")]
        public static extern int MsiCloseHandle(IntPtr handle);
        [DllImport("msi")]
        public static extern int MsiViewClose(IntPtr viewhandle);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiDatabaseGetPrimaryKeys(IntPtr msihandle,
            string TableName,       // the name of a specific table <case-sensitive>
            ref IntPtr recordhandle);         // returned record if ERROR_SUCCESS
        [DllImport("msi")]
        public static extern IntPtr MsiCreateRecord(
            int Params);                   // the number of data fields
        [DllImport("msi")]
        public static extern bool MsiRecordIsNull(IntPtr recordhandle,
            int Field);
        [DllImport("msi")]
        public static extern int MsiRecordDataSize(IntPtr recordhandle,
            int Field);
        [DllImport("msi")]
        public static extern int MsiRecordSetInteger(IntPtr recordhandle,
            int Field,
            int Value);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiRecordSetString(IntPtr recordhandle,
            int Field,
            string Value);
        [DllImport("msi")]
        public static extern int MsiRecordGetInteger(IntPtr recordhandle,
            int Field);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiRecordGetString(IntPtr recordhandle,
            int Field,
            StringBuilder ValueBuffer,       // buffer for returned value
            ref int length);            // in/out buffer character count
        [DllImport("msi")]
        public static extern int MsiRecordGetFieldCount(IntPtr recordhandle);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiRecordSetStream(IntPtr recordhandle,
            int Field,
            string FilePath);   // path to file containing stream data
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiRecordReadStream(IntPtr recordhandle,
            int Field,
            byte[] DataBuffer,     // buffer to receive bytes from stream
            ref int len);   // in/out buffer byte count
        [DllImport("msi")]
        public static extern int MsiRecordClearData(IntPtr recordhandle);
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnumProducts(
            int iProductIndex,    // 0-based index into registered products
            StringBuilder ProductBuffer);    // buffer of char count: 39 (size of string GUID)
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnumRelatedProducts(
            string UpgradeCode,    // upgrade code of products to enumerate
            int dwReserved,       // reserved, must be 0
            int iProductIndex,    // 0-based index into registered products
            StringBuilder ProductBuffer);    // buffer of char count: 39 (size of string GUID)
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnumFeatures(
            string szProduct,
            int iFeatureIndex,  // 0-based index into published features
            StringBuilder FeatureBuffer,   // feature name buffer,   size=MAX_FEATURE_CHARS+1
            StringBuilder ParentBuffer);   // parent feature buffer, size=MAX_FEATURE_CHARS+1
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnumClients(
            string szComponent,
            int iProductIndex,    // 0-based index into client products
            StringBuilder ProductBuffer);    // buffer of char count: 39 (size of string GUID)
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiEnumComponentQualifiers(
            string szComponent,         // generic component ID that is qualified
            int iIndex,	           // 0-based index into qualifiers
            StringBuilder QualifierBuffer,      // qualifier buffer
            ref int QualifierBufferLength,   // in/out qualifier buffer character count
            StringBuilder ApplicationDataBuffer,    // description buffer
            ref int ApplicationDataBufferLength); // in/out description buffer character count
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiGetSummaryInformation(IntPtr msihandle, // 0 if not open
            string szDatabasePath,  // path to database, 0 if database handle supplied
            int uiUpdateCount,    // maximium number of updated values, 0 to open read-only
            ref IntPtr SummaryInfo); // returned handle to summary information data
        [DllImport("msi")]
        public static extern int MsiSummaryInfoGetPropertyCount(IntPtr SummaryInfo,
            ref int PropertyCount); // pointer to location to return total property count
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiSummaryInfoSetProperty(IntPtr SummaryInfo,
            int uiProperty,     // property ID, one of allowed values for summary information
            int uiDataType,     // VT_I4, VT_LPSTR, VT_FILETIME, or VT_EMPTY
            /*INT*/    int iValue,         // integer value, used only if integer property
            ref	Com.FILETIME pftValue,      // pointer to filetime value, used only if datetime property
            string Value);       // text value, used only if string property
        [DllImport("msi", CharSet = CharSet.Auto)]
        public static extern int MsiSummaryInfoGetProperty(IntPtr SummaryInfo,
            int uiProperty,     // property ID, one of allowed values for summary information
            ref int uiDataType,   // returned type: VT_I4, VT_LPSTR, VT_FILETIME, VT_EMPTY
            /*INT*/     ref int Value,      // returned integer property data
            ref	Com.FILETIME pftValue,      // returned datetime property data
            StringBuilder ValueBuffer,     // buffer to return string property data
            ref int ValueBufferLength); // in/out buffer character count
        [DllImport("msi")]
        public static extern int MsiSummaryInfoPersist(IntPtr SummaryInfo);

        [StructLayout(LayoutKind.Sequential)]
        public struct MSIPATCHSEQUENCE
        {
            public string patchData;
            public int patchDataType;
            public int order;
            public int status;
        }

        public const int INSTALLMESSAGE_FATALEXIT = 0x00000000; // premature termination, possibly fatal OOM
        public const int INSTALLMESSAGE_ERROR = 0x01000000; // formatted error message
        public const int INSTALLMESSAGE_WARNING = 0x02000000; // formatted warning message
        public const int INSTALLMESSAGE_USER = 0x03000000; // user request message
        public const int INSTALLMESSAGE_INFO = 0x04000000; // informative message for log
        public const int INSTALLMESSAGE_FILESINUSE = 0x05000000; // list of files in use that need to be replaced
        public const int INSTALLMESSAGE_RESOLVESOURCE = 0x06000000; // request to determine a valid source location
        public const int INSTALLMESSAGE_OUTOFDISKSPACE = 0x07000000; // insufficient disk space message
        public const int INSTALLMESSAGE_ACTIONSTART = 0x08000000; // start of action: action name & description
        public const int INSTALLMESSAGE_ACTIONDATA = 0x09000000; // formatted data associated with individual action item
        public const int INSTALLMESSAGE_PROGRESS = 0x0A000000; // progress gauge info: units so far, total
        public const int INSTALLMESSAGE_COMMONDATA = 0x0B000000; // product info for dialog: language Id, dialog caption
        public const int INSTALLMESSAGE_INITIALIZE = 0x0C000000; // sent prior to UI initialization, no string data
        public const int INSTALLMESSAGE_TERMINATE = 0x0D000000; // sent after UI termination, no string data
        public const int INSTALLMESSAGE_SHOWDIALOG = 0x0E000000; // sent prior to display or authored dialog or wizard
        public const int INSTALLUILEVEL_NOCHANGE = 0;    // UI level is unchanged
        public const int INSTALLUILEVEL_DEFAULT = 1;    // default UI is used
        public const int INSTALLUILEVEL_NONE = 2;    // completely silent installation
        public const int INSTALLUILEVEL_BASIC = 3;    // simple progress and error handling
        public const int INSTALLUILEVEL_REDUCED = 4;    // authored UI, wizard dialogs suppressed
        public const int INSTALLUILEVEL_FULL = 5;    // authored UI with wizards, progress, errors
        public const int INSTALLUILEVEL_ENDDIALOG = 0x80; // display success/failure dialog at end of install
        public const int INSTALLUILEVEL_PROGRESSONLY = 0x40; // display only progress dialog
        public const int INSTALLSTATE_NOTUSED = -7;  // component disabled
        public const int INSTALLSTATE_BADCONFIG = -6; // configuration data corrupt
        public const int INSTALLSTATE_INCOMPLETE = -5; // installation suspended or in progress
        public const int INSTALLSTATE_SOURCEABSENT = -4;  // run from source, source is unavailable
        public const int INSTALLSTATE_MOREDATA = -3;  // return buffer overflow
        public const int INSTALLSTATE_INVALIDARG = -2;  // invalid function argument
        public const int INSTALLSTATE_UNKNOWN = -1;  // unrecognized product or feature
        public const int INSTALLSTATE_BROKEN = 0;  // broken
        public const int INSTALLSTATE_ADVERTISED = 1;  // advertised feature
        public const int INSTALLSTATE_REMOVED = 1;  // component being removed (action state, not settable)
        public const int INSTALLSTATE_ABSENT = 2;  // uninstalled (or action state absent but clients remain)
        public const int INSTALLSTATE_LOCAL = 3;  // installed on local drive
        public const int INSTALLSTATE_SOURCE = 4;  // run from source, CD or net
        public const int INSTALLSTATE_DEFAULT = 5;  // use default, local or source
        public const int USERINFOSTATE_MOREDATA = -3;  // return buffer overflow
        public const int USERINFOSTATE_INVALIDARG = -2;  // invalid function argument
        public const int USERINFOSTATE_UNKNOWN = -1;  // unrecognized product
        public const int USERINFOSTATE_ABSENT = 0;  // user info and PID not initialized
        public const int USERINFOSTATE_PRESENT = 1;  // user info and PID initialized
        public const int INSTALLLEVEL_DEFAULT = 0;      // install authored default
        public const int INSTALLLEVEL_MINIMUM = 1;      // install only required features
        public const int INSTALLLEVEL_MAXIMUM = 0xFFFF; // install all features
        public const int REINSTALLMODE_REPAIR = 0x00000001;  // Reserved bit - currently ignored
        public const int REINSTALLMODE_FILEMISSING = 0x00000002;  // Reinstall only if file is missing
        public const int REINSTALLMODE_FILEOLDERVERSION = 0x00000004;  // Reinstall if file is missing, or older version
        public const int REINSTALLMODE_FILEEQUALVERSION = 0x00000008;  // Reinstall if file is missing, or equal or older version
        public const int REINSTALLMODE_FILEEXACT = 0x00000010;  // Reinstall if file is missing, or not exact version
        public const int REINSTALLMODE_FILEVERIFY = 0x00000020;  // checksum executables, reinstall if missing or corrupt
        public const int REINSTALLMODE_FILEREPLACE = 0x00000040;  // Reinstall all files, regardless of version
        public const int REINSTALLMODE_MACHINEDATA = 0x00000080;  // insure required machine reg entries
        public const int REINSTALLMODE_USERDATA = 0x00000100;  // insure required user reg entries
        public const int REINSTALLMODE_SHORTCUT = 0x00000200;  // validate shortcuts items
        public const int REINSTALLMODE_PACKAGE = 0x00000400;  // use re-cache source install package
        public const int INSTALLLOGMODE_FATALEXIT = (1 << (0x00 >> 24));
        public const int INSTALLLOGMODE_ERROR = (1 << (0x01 >> 24));
        public const int INSTALLLOGMODE_WARNING = (1 << (0x02 >> 24));
        public const int INSTALLLOGMODE_USER = (1 << (0x03 >> 24));
        public const int INSTALLLOGMODE_INFO = (1 << (0x04 >> 24));
        public const int INSTALLLOGMODE_RESOLVESOURCE = (1 << (0x06 >> 24));
        public const int INSTALLLOGMODE_OUTOFDISKSPACE = (1 << (0x07 >> 24));
        public const int INSTALLLOGMODE_ACTIONSTART = (1 << (0x08 >> 24));
        public const int INSTALLLOGMODE_ACTIONDATA = (1 << (0x09 >> 24));
        public const int INSTALLLOGMODE_COMMONDATA = (1 << (0x0B >> 24));
        public const int INSTALLLOGMODE_PROPERTYDUMP = (1 << (0x0A >> 24)); // log only
        public const int INSTALLLOGMODE_VERBOSE = (1 << (0x0C >> 24)); // log only
        public const int INSTALLLOGMODE_PROGRESS = (1 << (0x0A >> 24)); // external handler only
        public const int INSTALLLOGMODE_INITIALIZE = (1 << (0x0C >> 24)); // external handler only
        public const int INSTALLLOGMODE_TERMINATE = (1 << (0x0D >> 24)); // external handler only
        public const int INSTALLLOGMODE_SHOWDIALOG = (1 << (0x0E >> 24)); // external handler only
        public const int INSTALLLOGATTRIBUTES_APPEND = (1 << 0);
        public const int INSTALLLOGATTRIBUTES_FLUSHEACHLINE = (1 << 1);
        public const int INSTALLFEATUREATTRIBUTE_FAVORLOCAL = 1 << 0;
        public const int INSTALLFEATUREATTRIBUTE_FAVORSOURCE = 1 << 1;
        public const int INSTALLFEATUREATTRIBUTE_FOLLOWPARENT = 1 << 2;
        public const int INSTALLFEATUREATTRIBUTE_FAVORADVERTISE = 1 << 3;
        public const int INSTALLFEATUREATTRIBUTE_DISALLOWADVERTISE = 1 << 4;
        public const int INSTALLFEATUREATTRIBUTE_NOUNSUPPORTEDADVERTISE = 1 << 5;
        public const int INSTALLMODE_NOSOURCERESOLUTION = -3;  // skip source resolution
        public const int INSTALLMODE_NODETECTION = -2;  // skip detection
        public const int INSTALLMODE_EXISTING = -1;  // provide, if available
        public const int INSTALLMODE_DEFAULT = 0;  // install, if absent
        public const int MAX_FEATURE_CHARS = 38;   // maximum chars in feature name (same as string GUID)
        public const string INSTALLPROPERTY_PACKAGENAME = "PackageName";
        public const string INSTALLPROPERTY_TRANSFORMS = "Transforms";
        public const string INSTALLPROPERTY_LANGUAGE = "Language";
        public const string INSTALLPROPERTY_PRODUCTNAME = "ProductName";
        public const string INSTALLPROPERTY_ASSIGNMENTTYPE = "AssignmentType";
        public const string INSTALLPROPERTY_PACKAGECODE = "PackageCode";
        public const string INSTALLPROPERTY_VERSION = "Version";
        public const string INSTALLPROPERTY_PRODUCTICON = "ProductIcon";
        public const string INSTALLPROPERTY_INSTALLEDPRODUCTNAME = "InstalledProductName";
        public const string INSTALLPROPERTY_VERSIONSTRING = "VersionString";
        public const string INSTALLPROPERTY_HELPLINK = "HelpLink";
        public const string INSTALLPROPERTY_HELPTELEPHONE = "HelpTelephone";
        public const string INSTALLPROPERTY_INSTALLLOCATION = "InstallLocation";
        public const string INSTALLPROPERTY_INSTALLSOURCE = "InstallSource";
        public const string INSTALLPROPERTY_INSTALLDATE = "InstallDate";
        public const string INSTALLPROPERTY_PUBLISHER = "Publisher";
        public const string INSTALLPROPERTY_LOCALPACKAGE = "LocalPackage";
        public const string INSTALLPROPERTY_URLINFOABOUT = "URLInfoAbout";
        public const string INSTALLPROPERTY_URLUPDATEINFO = "URLUpdateInfo";
        public const string INSTALLPROPERTY_VERSIONMINOR = "VersionMinor";
        public const string INSTALLPROPERTY_VERSIONMAJOR = "VersionMajor";
        public const int INSTALLTYPE_DEFAULT = 0;   // set to indicate default behavior
        public const int INSTALLTYPE_NETWORK_IMAGE = 1;   // set to indicate network install
        public const int MSIDBOPEN_READONLY = 0; // database open read-only, no persistent changes
        public const int MSIDBOPEN_TRANSACT = 1;  // database read/write in transaction mode
        public const int MSIDBOPEN_DIRECT = 2;  // database direct read/write without transaction
        public const int MSIDBOPEN_CREATE = 3;  // create new database, transact mode read/write
        public const int MSIDBOPEN_CREATEDIRECT = 4;  // create new database, direct mode read/writepublic const string MSIDBOPEN_READONLY     =  "0"; // database open read-only, no persistent changes
        public const int MSIDBSTATE_ERROR = -1;  // invalid database handle
        public const int MSIDBSTATE_READ = 0;  // database open read-only, no persistent changes
        public const int MSIDBSTATE_WRITE = 1;  // database readable and updatable
        public const int MSIMODIFY_SEEK = -1;  // reposition to current record primary key
        public const int MSIMODIFY_REFRESH = 0;  // refetch current record data
        public const int MSIMODIFY_INSERT = 1;  // insert new record, fails if matching key exists
        public const int MSIMODIFY_UPDATE = 2;  // update existing non-key data of fetched record
        public const int MSIMODIFY_ASSIGN = 3;  // insert record, replacing any existing record
        public const int MSIMODIFY_REPLACE = 4;  // update record, delete old if primary key edit
        public const int MSIMODIFY_MERGE = 5;  // fails if record with duplicate key not identical
        public const int MSIMODIFY_DELETE = 6;  // remove row referenced by this record from table
        public const int MSIMODIFY_INSERT_TEMPORARY = 7;  // insert a temporary record
        public const int MSIMODIFY_VALIDATE = 8;  // validate a fetched record
        public const int MSIMODIFY_VALIDATE_NEW = 9;  // validate a new record
        public const int MSIMODIFY_VALIDATE_FIELD = 10; // validate field(s) of an incomplete record
        public const int MSIMODIFY_VALIDATE_DELETE = 11; // validate before deleting record
        public const int MSICOLINFO_NAMES = 0;  // return column names
        public const int MSICOLINFO_TYPES = 1;  // return column definitions, datatype code followed by width
        public const int MSICONDITION_FALSE = 0;  // expression evaluates to False
        public const int MSICONDITION_TRUE = 1;  // expression evaluates to True
        public const int MSICONDITION_NONE = 2;  // no expression present
        public const int MSICONDITION_ERROR = 3;  // syntax error in expression
        public const int MSICOSTTREE_SELFONLY = 0;
        public const int MSICOSTTREE_CHILDREN = 1;
        public const int MSICOSTTREE_PARENTS = 2;
        public const int MSICOSTTREE_RESERVED = 3;	// Reserved for future use
        public const int PID_DICTIONARY = (0);// integer count + array of entries
        public const int PID_CODEPAGE = (0x1);// short integer
        public const int PID_TITLE = 2;  // string
        public const int PID_SUBJECT = 3;  // string
        public const int PID_AUTHOR = 4; // string
        public const int PID_KEYWORDS = 5;  // string
        public const int PID_COMMENTS = 6;  // string
        public const int PID_TEMPLATE = 7; // string
        public const int PID_LASTAUTHOR = 8;  // string
        public const int PID_REVNUMBER = 9;  // string
        public const int PID_EDITTIME = 10;  // datatime
        public const int PID_LASTPRINTED = 11;  // datetime
        public const int PID_CREATE_DTM = 12;  // datetime
        public const int PID_LASTSAVE_DTM = 13;  // datetime
        public const int PID_PAGECOUNT = 14;  // integer 
        public const int PID_WORDCOUNT = 15; // integer 
        public const int PID_CHARCOUNT = 16; // integer 
        public const int PID_THUMBNAIL = 17;  // clipboard format + metafile/bitmap (not supported)
        public const int PID_APPNAME = 18;  // string
        public const int PID_SECURITY = 19; // integer
        public const int PID_MSIVERSION = PID_PAGECOUNT;  // integer, Installer version number (major*100+minor)
        public const int PID_MSISOURCE = PID_WORDCOUNT;  // integer, type of file image, short/long, media/tree
        public const int PID_MSIRESTRICT = PID_CHARCOUNT;  // integer, transform restriction
        public const int MSITRANSFORM_ERROR_ADDEXISTINGROW = 0x1;
        public const int MSITRANSFORM_ERROR_DELMISSINGROW = 0x2;
        public const int MSITRANSFORM_ERROR_ADDEXISTINGTABLE = 0x4;
        public const int MSITRANSFORM_ERROR_DELMISSINGTABLE = 0x8;
        public const int MSITRANSFORM_ERROR_UPDATEMISSINGROW = 0x10;
        public const int MSITRANSFORM_ERROR_CHANGECODEPAGE = 0x20;
        public const int MSITRANSFORM_ERROR_VIEWTRANSFORM = 0x100;
        public const int MSITRANSFORM_VALIDATE_LANGUAGE = 0x00000001; // Default language must match base database. 
        public const int MSITRANSFORM_VALIDATE_PRODUCT = 0x00000002; // Product must match base database. 
        public const int MSITRANSFORM_VALIDATE_MAJORVERSION = 0x00000008; // Check major version only. 
        public const int MSITRANSFORM_VALIDATE_MINORVERSION = 0x00000010; // Check major and minor versions only. 
        public const int MSITRANSFORM_VALIDATE_UPDATEVERSION = 0x00000020; // Check major, minor, and update versions. 
        public const int MSITRANSFORM_VALIDATE_NEWLESSBASEVERSION = 0x00000040; // Installed version < base version. 
        public const int MSITRANSFORM_VALIDATE_NEWLESSEQUALBASEVERSION = 0x00000080; // Installed version <= base version. 
        public const int MSITRANSFORM_VALIDATE_NEWEQUALBASEVERSION = 0x00000100; // Installed version = base version. 
        public const int MSITRANSFORM_VALIDATE_NEWGREATEREQUALBASEVERSION = 0x00000200; // Installed version >= base version. 
        public const int MSITRANSFORM_VALIDATE_NEWGREATERBASEVERSION = 0x00000400; // Installed version > base version. 
        public const int MSITRANSFORM_VALIDATE_UPGRADECODE = 0x00000800; // UpgradeCode must match base database. 
        #endregion
    }
}
